package com.handler

import com.AwsUtils
import com.Config
import com.Main.Companion.scanner
import com.VerificationUtils.randomString
import com.amazonaws.services.cloudfront.AmazonCloudFront
import com.amazonaws.services.cloudfront.model.*
import com.isNumeric
import org.slf4j.LoggerFactory

/**
 * 执行一次更新缓存
 */
class InvalidationHandler : BaseHandler<String?>(null) {
    private var amazonCloudFront: AmazonCloudFront? = null

    public override fun execute() {
        //注意你只能有三个并发的失效; 失效似乎需要10-30分钟。
        if (Config.updatePath.isNullOrBlank()) {
            val rootPath = packCmd.rootPath
            if (rootPath.isNullOrBlank()) { // 如果是null
                Config.updatePath = Config.DEFAULT_PATH
            } else {
                Config.updatePath =
                    (if (rootPath.startsWith("/")) "" else "/") + rootPath + (if (rootPath.endsWith("/")) "*" else "/*")
            }
        }
        amazonCloudFront = AwsUtils.awsUtils.initAmazonCloudFront()
        if (packCmd.distributionId.isNullOrBlank()) {
            distribution
        }
        if (packCmd.distributionId == null || Config.updatePath == null) {
            System.err.println("无效的输入: distributionId = " + packCmd.distributionId + ", updatePath = " + Config.updatePath)
        } else {
            println("匹配成功: distributionId = " + packCmd.distributionId + ", updatePath = " + Config.updatePath)
            this.invalidation()
        }
    }



    private val distribution: Unit
        /**
         * 根据已知桶名字去寻找id 如果未找到  则使用手动选择
         */
        get() {
            val distributions = amazonCloudFront!!.listDistributions(ListDistributionsRequest())
            val lists = distributions.distributionList.items
            if (packCmd.bucketName.isNullOrBlank()) {
                getDistribution(lists)
                return
            }
            println("寻找桶名为 [" + packCmd.bucketName + "] 的失效服务器...")
            var name: String
            var findName: String? = null
            // 查找更新id
            for (distributionSummary in lists) {
                val origins = distributionSummary.origins.items
                for (origin in origins) {
                    name = origin.domainName
                    name = name.substringBefore(".")
                    if (name == packCmd.bucketName) { // 是否找到桶
                        findName = name
                        println("找到匹配桶名 = " + name + ", 桶源路径= " + origin.domainName)
                        break
                    }
                }
                if (!findName.isNullOrBlank()) {
                    packCmd.distributionId = distributionSummary.id
                    break
                }
            }

            if (packCmd.distributionId.isNullOrBlank()) {
                getDistribution(lists)
            }
        }

    private fun getDistribution(lists: List<DistributionSummary>) {
        println("选择失效服务器 ")
        var distributionSummary: DistributionSummary
        for (i in lists.indices) {
            distributionSummary = lists[i]
            println(
                i.toString() + " | " +
                        " | " + distributionSummary.id +
                        " | " + distributionSummary.comment +
                        " | " + distributionSummary.domainName
                        + " | " + distributionSummary.status
            )
        }
        var cmd = scanner!!.nextLine().trim { it <= ' ' }
        var disId = 0

        Character.isDigit(1)

        if (isNumeric(cmd) && (cmd.toInt().also { disId = it }) < lists.size) {
            packCmd.distributionId = lists[disId].id
            println("失效服务器 = " + lists[disId].comment)
            println("输入失效路径 /*  /a/*  /a/d/c/ 默认 /* 多个失效路径用空格隔开(最多同时失效3个路径) ")
            cmd = scanner!!.nextLine().trim { it <= ' ' }
            if (cmd.isBlank()) {
                System.err.println("无效的输入")
                getDistribution(lists)
                return
            }
            Config.updatePath = cmd
        } else {
            System.err.println("无效的输入")
            getDistribution(lists)
        }
    }

    private fun invalidation() {
        val invalidations = Config.updatePath!!.split("\\s+".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
        println("失效路径数量 = " + invalidations.size)
        val paths = Paths().withItems(*invalidations).withQuantity(invalidations.size)

        val callerReference = randomString(14)

        //        System.out.println("callerReference = "+callerReference);
        val invalidationBatch = InvalidationBatch(paths, callerReference)

        val createInvalidationRequest =
            CreateInvalidationRequest(packCmd.distributionId, invalidationBatch)

        val result = amazonCloudFront!!.createInvalidation(createInvalidationRequest)
        println("Invalidation ID = " + result.invalidation.id)

        while (true) {
            try {
                Thread.sleep(1000)
            } catch (e: InterruptedException) {
                LoggerFactory.getLogger(javaClass).error(null, e)
            }

            val result1 = amazonCloudFront!!.getInvalidation(
                GetInvalidationRequest(
                    packCmd.distributionId, result.invalidation.id
                )
            )
            val status = result1.invalidation.status
            print("\r")
            print("%n% ")
            print(status)
            if (status == "Completed") break
        }

        println()
        println("失效操作完成!")
    }
}
